/**
 * 
 */
package cz.cvut.fit.bugtrac.dao;

import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.google.appengine.api.datastore.Key;

import cz.cvut.fit.bugtrac.exception.BugTracException;
import cz.cvut.fit.bugtrac.persistence.AbstractBugTracEntity;

/**
 * parent for all DAO - provides basic DB operations for entity beans
 * 
 * @author Jarec
 * 
 */
public abstract class AbstractBugTracDAO<T extends AbstractBugTracEntity>
		implements BugTracDAO<T> {

	protected static transient Logger log = Logger
			.getLogger(AbstractBugTracDAO.class.getName());

	@PersistenceContext
	protected EntityManager em;

	protected T getById(Class<T> clazz, Key id) throws BugTracException {
		T entity = em.find(clazz, id);
		if (entity == null) {
			throw new BugTracException("Entity not found: " + clazz + ", id="
					+ id);
		} else {
			return entity;
		}
	}

	@Override
	public T getById(Key id) throws BugTracException {
		return getById(getEntityClass(), id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cz.cvut.fit.bugtrac.dao.BugTracDAO#save(cz.cvut.fit.bugtrac.persistence
	 * .AbstractBugTracEntity)
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void save(T entity) {
		em.persist(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cz.cvut.fit.bugtrac.dao.BugTracDAO#refresh(cz.cvut.fit.bugtrac.persistence
	 * .AbstractBugTracEntity)
	 */
	@Override
	public void refresh(T entity) {
		em.refresh(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cz.cvut.fit.bugtrac.dao.BugTracDAO#delete(cz.cvut.fit.bugtrac.persistence
	 * .AbstractBugTracEntity)
	 */
	@Override
	public void delete(T entity) {
		em.remove(entity);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cz.cvut.fit.bugtrac.dao.BugTracDAO#clear()
	 */
	@Override
	public void clear() {
		em.clear();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cz.cvut.fit.bugtrac.dao.BugTracDAO#merge(cz.cvut.fit.bugtrac.persistence
	 * .AbstractBugTracEntity)
	 */
	@Override
	public T merge(T entity) {
		return em.merge(entity);
	}

	public abstract Class<T> getEntityClass();

}
